package com.sdy.resdir.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sdy.auth.api.model.UserInfo;
import com.sdy.auth.client.service.SsoService;
import com.sdy.common.model.BizException;
import com.sdy.common.utils.Assert;
import com.sdy.dataadapter.DataAdapter;
import com.sdy.dataadapter.DbType;
import com.sdy.dataadapter.RawDataSource;
import com.sdy.resdir.biz.service.RdDbDictService;
import com.sdy.resdir.biz.model.RdDbDict;
import com.sdy.common.model.Response;
import com.sdy.resdir.biz.service.RdResDataItemService;
import com.sdy.resdir.biz.service.RdResourceDirDataService;
import com.sdy.resdir.biz.service.RdResourceDirService;
import com.sdy.usercenter.api.UserQueryApi;
import com.sdy.usercenter.api.dto.UserDTO;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.sdy.mvc.controller.BaseController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

/**
 * <p>
 * 数据源配置 前端控制器
 * </p>
 *
 * @author glm
 * @since 2019-12-24
 */
@Slf4j
@RestController
@Api(tags = "数据交换类数据库信息")

@SuppressWarnings("unchecked")
@RequestMapping("/rdDbDict")
public class RdDbDictController extends BaseController {
    @Autowired
    private RdDbDictService rdDbDictService;
    @Autowired
    private SsoService ssoService;
    @Autowired
    private UserQueryApi userQueryApi;
    @Autowired
    private RdResourceDirService rdResourceDirService;
    @Autowired
    private RdResDataItemService rdResDataItemService;
    @Autowired
    private RdResourceDirDataService rdResourceDirDataService;

    /**
     * 数据库列表
     *
     * @param page
     * @param dbDesc
     * @param dbType
     * @return
     */
    @ApiOperation(value = "数据库列表")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "dbDesc", value = "数据源名称"),
            @ApiImplicitParam(name = "dbType", value = "数据源类型")}
    )
    @GetMapping("/databaseList")
    public Response databaseList(HttpServletRequest request, Page page, String dbDesc, String dbType) {
        Integer userId = ssoService.getUserId(request);
        UserDTO user = userQueryApi.getUser(userId);
        LambdaQueryWrapper<RdDbDict> wrapper = new LambdaQueryWrapper<>();
        // 数据源名称模糊查询
        wrapper.like(StringUtils.isNotBlank(dbDesc), RdDbDict::getDbDesc, dbDesc);
        // 数据库类型查询
        wrapper.eq(StringUtils.isNotBlank(dbType), RdDbDict::getDbType, dbType);
        // 查看该部门下的数据库
        wrapper.eq(RdDbDict::getDeptId, user.getOwnDeptId());
        // 新增顺序倒序排序
        wrapper.orderByDesc(RdDbDict::getDbId);
        IPage dbList = rdDbDictService.page(page, wrapper);
        return Response.success(dbList);
    }


    @ApiOperation(value = "查询数据库详情")
    @ApiImplicitParam(name = "dbId", value = "数据库id")
    @GetMapping("/selectOneDatabase")
    public Response selectOneDatabase(Integer dbId) throws BizException {
        Assert.isNull(dbId, "无法获取资源id");
        RdDbDict rdDbDict = rdDbDictService.getById(dbId);
        return Response.success(rdDbDict);
    }

    /**
     * 测试新增数据库信息是否正确
     *
     * @param
     * @return
     */
    @ApiOperation("测试新增数据库信息是否正确")
    @ApiImplicitParam(name = "rdDbDict", value = "数据库信息")
    @GetMapping("/checkDatabase")
    public Response checkDatabase(RdDbDict rdDbDict) throws BizException {
        if (StringUtils.isNotBlank(rdDbDict.getDbDesc()) && StringUtils.isNotBlank(rdDbDict.getDbIp())
                && StringUtils.isNotBlank(rdDbDict.getDbName()) && StringUtils.isNotBlank(rdDbDict.getDbPasswd()) && StringUtils.isNotBlank(rdDbDict.getDbUser())
                && StringUtils.isNotBlank(rdDbDict.getDbType()) && rdDbDict.getDbPort() != null) {
            // 测试连接数据库
            if (checkDb(rdDbDict)) {
                return Response.error("请检查数据库类型");
            }
            // 尝试访问百度，判断网络是否正常
            try {
                URL url = new URL("http://baicu.com/");
                InputStream in = url.openStream();
                in.close();
            } catch (IOException e) {
                return Response.error("网络中断或不可用");
            }
            return Response.success("数据库测试连接成功");
        } else {
            return Response.error("请填写完整信息");
        }
    }


    @ApiOperation("新增数据库")
    @PostMapping("/saveDatabase")

    public Response saveDatabase(@RequestBody @ApiParam(name = "dbDesc & dbIp & dbName & dbPasswd & dbUser & dbType & dbPort",
            value = "数据源名称，数据库ip地址，数据库名称，数据库密码，数据库用户名，数据库类型，数据库端口")
                                         RdDbDict rdDbDict, HttpServletRequest request
    ) throws BizException {
        UserInfo userInfo = ssoService.getUserInfo(request);
        UserDTO user = userQueryApi.getUser(userInfo.getUserId());
        Assert.isNull(userInfo, "用户未登录");
        if (StringUtils.isNotBlank(rdDbDict.getDbDesc()) && StringUtils.isNotBlank(rdDbDict.getDbIp())
                && StringUtils.isNotBlank(rdDbDict.getDbName()) && StringUtils.isNotBlank(rdDbDict.getDbPasswd()) && StringUtils.isNotBlank(rdDbDict.getDbUser())
                && StringUtils.isNotBlank(rdDbDict.getDbType()) && rdDbDict.getDbPort() != null) {
            if (checkDb(rdDbDict)) {
                return Response.error("请检查数据库类型");
            }
            RdDbDict getRdDbDict = rdDbDictService.getOne(new LambdaQueryWrapper<RdDbDict>()
                    .eq(RdDbDict::getDbIp, rdDbDict.getDbIp())
                    .eq(RdDbDict::getDbPort, rdDbDict.getDbPort())
                    .eq(RdDbDict::getDbUser, rdDbDict.getDbUser())
                    .eq(RdDbDict::getDbName, rdDbDict.getDbName()));
            if (getRdDbDict != null) {
                Assert.isTrue(getRdDbDict.getDeptId() == null || getRdDbDict.getDeptName() == null, "该数据库已存在，但无法获取该数据库所存在部门信息");
                Assert.isTrue(getRdDbDict.getDeptId() != null && getRdDbDict.getDeptName() != null && user.getOwnDeptId().equals(getRdDbDict.getDeptId()), "该数据库已存在于本部门，请勿重复添加");
                Assert.isTrue(getRdDbDict.getDeptId() != null && getRdDbDict.getDeptName() != null && !user.getOwnDeptId().equals(getRdDbDict.getDeptId()), "该数据库已存在于部门：" + getRdDbDict.getDeptName() + "，请勿重复添加");
            }
            rdDbDict.setDeptId(user.getOwnDeptId())
                    .setDeptName(user.getOwnDeptName());
            return Response.success(rdDbDictService.save(rdDbDict));
        } else {
            return Response.error("请填写完整信息");
        }
    }

    /**
     * 测试连接数据库
     *
     * @param rdDbDict
     * @return
     * @throws BizException
     */
    private boolean checkDb(RdDbDict rdDbDict) throws BizException {
        if (rdDbDict.getDbType() != null && "MYSQL".equals(rdDbDict.getDbType())) {
            DataAdapter dataAdapter = new DataAdapter(new RawDataSource(DbType.MYSQL, rdDbDict.getDbIp(), rdDbDict.getDbPort(), rdDbDict.getDbName()
                    , rdDbDict.getDbUser(), rdDbDict.getDbPasswd(), null));
            boolean checkResult = dataAdapter.checkConnection(2000);
            Assert.notTrue(checkResult, "数据库测试连接失败，请检查参数");
        } else if (rdDbDict.getDbType() != null && "ORACLE".equals(rdDbDict.getDbType())) {
            DataAdapter dataAdapter = new DataAdapter(new RawDataSource(DbType.ORACLE, rdDbDict.getDbIp(), rdDbDict.getDbPort(), rdDbDict.getDbName()
                    , rdDbDict.getDbUser(), rdDbDict.getDbPasswd(), null));
            boolean checkResult = dataAdapter.checkConnection(2000);
            Assert.notTrue(checkResult, "数据库测试连接失败，请检查参数");
        } else {
            return true;
        }
        return false;
    }

}
